iT邦幫忙

2022 iThome 鐵人賽

DAY 4
0
自我挑戰組

laravel+vue 學習系列 第 4

Day4. Controller

  • 分享至 

  • xImage
  •  

一、Controller 作用

  • 將單一或多個相同的路由邏輯放到同一個 Controller Class 內
  • Controller Class 內通常會使用 CRUD 架構建立 function, 來對單一或多個資料表(model)做操作

二、建立 Controller 與 Route 綁定

  1. 使用 Artisan 命令列工具產生
    php artisan make:controller ProductController
  1. 在 Controller 建立一個 public function index(), 來接收與回應使用者請求
    class ProductController extends Controller
    {
        // index 要處理的邏輯
        // ...
    }
  1. 設定路由指向 Controller (基本綁定方式)
    # 到 routes\web.php 內設定路由
    # 目前沒有特別綁定 Class , 先用一般引入 Controller Class
    use App\Http\Controllers\ProductController;
    
    # 使用 tuple 語法指定 Controller
    Route::get('/product', [ProductController::class, 'index']);
  1. 基本用法回傳 html 頁面
    class ProductController extends Controller
    {
        public function index()
        {
            # 建立模板變數 title
            $binding['title'] = 'ProductController@index';
            
            # 回傳 html, 使用 resources\views\product\list.blade.php 模板
            # 第二個參數將要使用的變數給模板($binding)
            return view('product.list', $binding);
        }
    }
  • 路由 /product 回傳的頁面
    https://ithelp.ithome.com.tw/upload/images/20220909/20128127DBPDSIHtvN.png

三、取得用戶輸入

  1. 設定兩個路由來測試
    # routes\web.php 建立 /product/create 路由(GET、POST)產生表單頁面與接收表單訊息
    # 建立 product 群組路由
    Route::group(['prefix' => 'product'], function(){
        Route::get('/', [ProductController::class, 'index']);
        Route::get('/create', [ProductController::class, 'create']);
        
        # 設定路由名稱方便表單使用
        Route::post(
            '/create', 
            [ProductController::class, 'store']
        )->name('product.createProcess');
    });
  1. 建立 Controller 對應的 function 處理請求
  • 建立 create() 方法回傳輸入表單
    class ProductController extends Controller
    {
        // ... 其他程式省略

        public function create()
        {
            $binding['title'] = 'GET -> ProductController@create';
            
            # blade from action 設定為 
            return view('product.create', $binding);
        }
    }
  • create product 表單頁面
    https://ithelp.ithome.com.tw/upload/images/20220909/20128127JxgS6qRnuU.png

  • 建立 store() 方法接收使用者輸入參數, 接受方法有三種
    a. 使用全域輔助函數 request()

        class ProductController extends Controller
        {
            // ... 其他程式省略
    
            public function store(){
                $request = request()->all();
    
                echo "<pre>";
                print_r($request);
                exit;
            }
        }
    
    • 接收到的內容
      https://ithelp.ithome.com.tw/upload/images/20220909/20128127FSCWHfrGFT.png

    b. 使用靜態介面

        # Controller 內引用 Request
        use Request;
    
        class ProductController extends Controller
        {
            // ... 其他程式省略
    
            # 使用 only 只取使用者輸入的欄位值
            public function store(){
                // $request = request()->all();
                $request = Request::only(['name', 'simpleintro']);
    
                echo "<pre>";
                print_r($request);
                exit;
            }
        }
    
    • 接收到的內容
      https://ithelp.ithome.com.tw/upload/images/20220909/20128127tkzQQzFZoP.png

    c. 使用依賴項目注入(typehint 方法簽章)
    * typehint 告知 PHP 此參數必須是要傳入所指定的類型

        # 引入 Illuminate\Http\Request
        use Illuminate\Http\Request;
    
        class ProductController extends Controller
        {
            // ... 其他程式省略
    
            public function store(Request $request){
                // $request = request()->all();
                // $request = Request::only(['name', 'simpleintro']);
                $input = $request->only(['name', 'simpleintro']);
    
                echo "<pre>";
                print_r($input);
                exit;
            }
        }
    

四、資源控制

  1. 資源控制器 ( REST/CRUD controller )

    • 在建立 Controller 時加上旗標 --resource, 生成預設方法 create(), update() 等, 快速建立資源
        php artisan make:controller ArticleController --resource
    
    • 綁定資源控制器
        # 設定路由綁定資源
        # route\web.php
        # 第一個參數為路由名稱後面會接相關方法
        # e.g. article.index
        Route::resource('article', 'App\Http\Controllers\ArticleController');
    
    • cmd 查看存在路由
        php artisan route:list
    

    https://ithelp.ithome.com.tw/upload/images/20220909/20128127fKWaCxmXjo.png

    • 指定只用部分路由
        # 使用 only 只用指定的路由
        Route::resource(
            'article', 
            'App\Http\Controllers\ArticleController', 
            [ 'only' => ['index', 'show'] ]
        );
    
        # 使用 except 不用排除指定的路由
        Route::resource(
            'article', 
            'App\Http\Controllers\ArticleController', 
            [ 'except' => ['index', 'show'] ]
        );
    
  2. API 資源控制器

    • 設定方式類似一般資源控制器,旗標改為 --api
        php artisan make:controller ArticleApiController --api
    
    • 綁定 API 資源控制器
        # 設定位置 route\api.php
        Route::apiResource('article', 'App\Http\Controllers\ArticleApiController');
    
    • 查看路由, 因 API 不會有表單頁, 所以預設不會有 create(), edit() 兩個方法
      https://ithelp.ithome.com.tw/upload/images/20220909/20128127TIIaHHjXCq.png

其他綁定方法

  1. 單一動作綁定
  • Controller 只會對應到一個路由時使用, 建立一個 __invoke() 方法
    # 建立一個 singleController 只負責處理一個路由
    class singleController extends Controller
    {
        public function __invoke(Product product)
        {
            // Controller 要做的事情
        }
    }
    
    # routes\web.php 設定路由
    Route::post('product/{product}/update_roduct', 'singleController');
  1. 路由 model 綁定
  • 設定時給一個路由參數用來指定路由使用哪個 Class 解析, 預設會將傳進來的當成 id (唯一值) 進到資料庫查詢該筆資料, 回傳資料的 model 物件
    a. 隱性綁定

        # 路由一般使用方式, 得到該筆資料
        Route::get('product/{id}', function($id){
            $product = Product::findOrFail($id);
        });
    
        # 隱性綁定 + typehint
        # Laravel 5.2 以後添加此功能
        Route::get('product/{product}', function( Product $product ){
            return view('product.view')->with('product', $product);
        });
    
        # 要改變綁定的資料庫欄位, 要在 model 設定 getRouteKeyName() 方法
        # 設定 serial_number 為綁定的欄位
        public function getRouteKeyName(){
            return 'serial_number';
        }        
    

    b. 自訂路由 model 綁定

    • 到 App\Providers\RouteServiceiceProvider 的 boot() 方法設定
        public function boot(){
    
            # 當路由中有設定 {product} 變數時會轉成 model Product 物件
            Route::model('product', Product::class);
        }
    

上一篇
Day3. 路由 Route
下一篇
Day5. 補充 Controller + 建立路由
系列文
laravel+vue 學習32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言